﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;

namespace DogJson
{
    public enum JsonValueType : byte
    {
        None = 0,
        String = 1,
        Long = 2,
        Double = 3,
        Boolean = 4,
        Object = 5,
        Array = 6,
    }
    public unsafe class JsonRender
    {
        static double[] pow309 = new double[309];
        static double[] pow309negative = new double[309];
        private static bool initializedPow = false;


        private static object mutex = new object();
        private static bool initialized = false;
        private static JsonRender _ins = null;

        public static JsonRender Instance
        {
            get
            {
                if (!initialized)
                {
                    lock (mutex)
                    {
                        if (_ins == null)
                        {
                            _ins = new JsonRender();
                            initialized = true;
                        }
                    }
                }
                return _ins;
            }
        }

        public unsafe JsonRender(int jsonStackLength = 1024, int poolLength = 65536)
        {
            if (!initializedPow)
            {
                lock (pow309)
                {
                    lock (pow309negative)
                    {
                        for (int i = 0; i < 309; i++)
                        {
                            pow309[i] = Math.Pow(10, i);
                            pow309negative[i] = Math.Pow(10, -i);
                        }
                        initializedPow = true;
                    }
                }
            }

            this.jsonStackLength = jsonStackLength;
            this.poolLength = poolLength;


            stackIntPtr = Marshal.AllocHGlobal(jsonStackLength * Marshal.SizeOf(typeof(JsonValue*)));
            objectQueueIntPtr = Marshal.AllocHGlobal(poolLength * Marshal.SizeOf(typeof(JsonObject)));
            poolIntPtr = Marshal.AllocHGlobal(poolLength * Marshal.SizeOf(typeof(JsonValue)));

            //pool = (JsonValue*)poolIntPtr.ToPointer();
            pool = new JsonValue[poolLength];
            objectQueue = new JsonObject[poolLength];
            stack = new int[jsonStackLength];


            //pool = (JsonValue*)poolIntPtr.ToPointer();
            //jsonStack = (JsonValue**)jsonStackIntPtr.ToPointer();
            //jsonStackHead = jsonStack[0];


            fixed (char* vs = "true")
            {
                truelong = *(long*)vs;
            }
            fixed (char* vs = "fals")
            {
                falslong = *(long*)vs;
            }
            fixed (char* vs = "null")
            {
                nulllong = *(long*)vs;
            }
            fixed (char* vs = "alse")
            {
                alselong = *(long*)vs;
            }
            fixed (char* vs = "type")
            {
                typelong = *(long*)vs;
            }
            fixed (char* vs = "valu")
            {
                valulong = *(long*)vs;
            }
            fixed (char* vs = "crea")
            {
                crealong = *(long*)vs;
            }
            fixed (char* vs = "te")
            {
                telong = *(int*)vs;
            }
        }

        long truelong;
        long falslong;
        long nulllong;
        long alselong;
        long typelong;
        long valulong;
        long crealong;
        int telong;


        IntPtr stackIntPtr;
        IntPtr poolIntPtr;
        IntPtr objectQueueIntPtr;

        //[StructLayout(LayoutKind.Explicit)]
        public struct JsonObject
        {
            //[FieldOffset(0)]
            public int keyStringStart;
            public int keyStringLength;

            public int parentObjectIndex;

            public bool isObject;

            /// <summary>
            /// #create
            /// </summary>
            public bool isConstructor;

            /// <summary>
            /// #value
            /// </summary>
            public bool isCommandValue;


            public int arrayCount;

            public int arrayIndex;

            public int typeStartIndex;
            public int typeLength;
        }


        public class CreateObjectItem
        {
            public CreateObjectItem(int index)
            {
                this.index = index;
            }
            public object obj;
            public Type type;
            public Type sourceType;
            public FieldInfo fieldInfo;
            public string key;
            public Array objArray;
            public TypeCode ArrayItemTypeCode;
            public Type ArrayItemType;
            public int ArrayRank;
            public int[] ArrayRankLengths;
            public int[] ArrayRankIndex;

            public JsonObject jsonObject;

            public List<CreateObjectItem> sub = new List<CreateObjectItem>();
            public bool isValueType;
            public int index;
            public ICollectionArrayBase collectionArray;
            public ICollectionObjectBase collectionObject;
        }


        int keyStringStart = 0;
        int keyStringLength = 0;
        int vStringStart = 0;
        int vStringLength = 0;

        JsonObject[] objectQueue;
        JsonValue[] pool;
        int[] stack;


        int jsonStackLength = 1024;
        int poolLength = 65536;

        int stackIndex = 0;
        //bool nowIsArray = false;
        int poolIndex = 0;
        int objectQueueIndex = 0;

        unsafe string Debug(string str, int index, string txt)
        {
            int line = 1;
            int length = str.Length;
            fixed (char* vs = str)
            {
                char* now = vs;
                for (int i = 0; i < index; i++)
                {
                    if (*now == '\n')
                    {
                        ++line;
                    }
                    ++now;
                }
            }
            txt += " 第" + line + "行";
            return txt;
        }

        public unsafe int ReadJsonText(string str)
        {
            int length = str.Length;
            fixed (char* startChar = str)
            {
                char* now = startChar;
                int objectAnalysisNowIndex = 0;

                stackIndex = 0;
                poolIndex = 0;
                keyStringLength = 0;
                keyStringStart = 0;
                objectQueueIndex = 0;

                double v_double = 0;
                double v_decimal = 1;
                long v_long = 0;
                JsonValue json_value;
                bool fu = false;
                int i = 0;
                //先读初始状态 这里 先只支持{开头的数据
                for (; i < length; ++i, ++now)
                {
                    switch (*now)
                    {
                        case '{':
                            objectQueue[objectQueueIndex].parentObjectIndex = -1;
                            objectQueue[objectQueueIndex].keyStringStart = 0;
                            objectQueue[objectQueueIndex].keyStringLength = 1;
                            objectQueue[objectQueueIndex].isObject = true;

                            stack[stackIndex] = objectQueueIndex;
                            ++objectQueueIndex;
                            goto Run;
                        case ' ':
                        case '\t':
                        case '\r':
                        case '\n':
                            break;

                        case '"':
                        case ':':
                        case '}':
                        case '[':
                        case ']':
                        case ',':
                        default:
                            throw new Exception(Debug(str, i, "错误开头 " + *now));
                    }
                }
            Run:

                do
                {
                Loop:
                    if (stackIndex == -1)
                    {
                        break;
                    }
                    if (objectQueue[stack[stackIndex]].isObject)
                    {
                        goto State_Object;
                    }
                    else
                    {
                        goto State_Array;
                    }
                State_Object:
                    for (++i, ++now; i < length; ++i, ++now)
                    {
                        switch (*now)                                                             
                        {
                            case '"':
                                keyStringStart = i + 1;
                                //再找" 
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now == '"')
                                    {
                                        keyStringLength = i - keyStringStart;
                                        for (++i, ++now; i < length; ++i, ++now)
                                        {
                                            if (*now == ':')
                                            {
                                                if (*(startChar + keyStringStart) == '#')
                                                {
                                                    long nameLong = *(long*)(startChar + keyStringStart + 1);
                                                    switch (keyStringLength)
                                                    {
                                                        case 5:
                                                            if (nameLong == typelong)
                                                            {
                                                                for (++i, ++now; i < length; ++i, ++now)
                                                                {
                                                                    switch (*now)
                                                                    {
                                                                        case '"':
                                                                            int typeStartIndex = i + 1;

                                                                            for (++i, ++now; i < length; ++i, ++now)
                                                                            {
                                                                                if (*now == '"')
                                                                                {
                                                                                    int typeLength = i - typeStartIndex;
                                                                                    objectQueue[stack[stackIndex]].typeStartIndex = typeStartIndex;
                                                                                    objectQueue[stack[stackIndex]].typeLength = typeLength;
                                                                                    goto Run3;
                                                                                }
                                                                            }

                                                                            break;
                                                                        case ' ':
                                                                        case '\t':
                                                                        case '\r':
                                                                        case '\n':
                                                                            break;
                                                                        default:
                                                                            throw new Exception(Debug(str, i, "#type 后面必须是字符串 " + *now));
                                                                    }
                                                                }
                                                            }
                                                            break;

                                                        case 6:
                                                            if (nameLong == valulong && *(startChar + keyStringStart + 5) == 'e')
                                                            {
                                                                objectQueue[stack[stackIndex]].isCommandValue = true;
                                                                goto Run1;
                                                            }
                                                            break;

                                                        case 7:
                                                            if (nameLong == crealong
                                                             && *(int*)(startChar + keyStringStart + 5) == telong
                                                             )
                                                            {
                                                                objectQueue[stack[stackIndex]].isConstructor = true;
                                                                goto Run1;
                                                            }
                                                            break;
                                                        default:
                                                            throw new Exception(Debug(str, i, "# 未知指令" + *now));
                                                    }
                                                            throw new Exception(Debug(str, i, "# 未知指令" + *now));
                                                Run3:
                                                    // 下必 ,} 
                                                    for (++i, ++now; i < length; ++i, ++now)
                                                    {
                                                        switch (*now)
                                                        {
                                                            case ',':
                                                                goto State_Object;
                                                            case '}':
                                                                //string入队
                                                                //出栈 
                                                                --stackIndex;
                                                                if (objectQueue[stack[stackIndex]].isObject)
                                                                {
                                                                    goto State_Object;
                                                                }
                                                                else
                                                                {
                                                                    objectQueue[stack[stackIndex + 1]].arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                                                    ++objectQueue[stack[stackIndex]].arrayCount;
                                                                    goto State_Array;
                                                                }
                                                            //goto Loop;
                                                            case ' ':
                                                            case '\t':
                                                            case '\r':
                                                            case '\n':
                                                                break;
                                                            default:
                                                                throw new Exception("key:value后面只能是,或者}");
                                                        }
                                                    }
                                                    throw new Exception("key:value后面必须要跟,或者} 未正常 结尾");
                                                }


                                                goto Run1;
                                            }
                                        }
                                        throw new Exception("key后面需要:");
                                    }
                                }
                                throw new Exception("字符串未结束 ");
                            case '}':

                                //出栈 
                                --stackIndex;
                                if (stackIndex == -1)
                                {
                                    goto BACK;
                                }
                                if (objectQueue[stack[stackIndex]].isObject)
                                {
                                    goto State_Object;
                                }
                                else
                                {
                                    objectQueue[stack[stackIndex + 1]].arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                    ++objectQueue[stack[stackIndex]].arrayCount;
                                    goto State_Array;
                                }

                            case ' ':
                            case '\t':
                            case '\r':
                            case '\n':
                            case ',':
                                break;
                            default:
                                throw new Exception(Debug(str, i, "对象 下面只能有keyvalue结构 " + *now));
                        }
                    }

                    //下一个必出" 或}
                    for (++i, ++now; i < length; ++i, ++now)
                    {
                        switch (*now)
                        {
                            case '"':
                                keyStringStart = i + 1;
                                //再找" 
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now == '"')
                                    {
                                        keyStringLength = i - keyStringStart;
                                        for (++i, ++now; i < length; ++i, ++now)
                                        {
                                            if (*now == ':')
                                            {
                                                goto Run1;
                                            }
                                        }
                                        throw new Exception(Debug(str, i, "key后面需要: " + *now));
                                    }
                                }
                                throw new Exception(Debug(str, i, "字符串未结束 " + *now));

                            case '}':
                                //出栈 
                                --stackIndex;
                                if (stackIndex == -1)
                                {
                                    goto BACK;
                                }
                                if (objectQueue[stack[stackIndex]].isObject)
                                {
                                    goto State_Object;
                                }
                                else
                                {
                                    objectQueue[stack[stackIndex + 1]].arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                    ++objectQueue[stack[stackIndex]].arrayCount;
                                    goto State_Array;
                                }

                            case ' ':
                            case '\t':
                            case '\r':
                            case '\n':
                            case ',':
                                break;
                            default:
                                throw new Exception(Debug(str, i, "对象 下面只能有keyvalue结构 " + *now));
                        }
                    }
                Run1:
                    //key:后面只能是 布尔、数值、对象 、数组 再找下 " { [ 其他  不能是 } : , ]  

                    for (++i, ++now; i < length; ++i, ++now)
                    {
                        switch (*now)
                        {
                            case '"':
                                vStringStart = i + 1;

                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now == '"')
                                    {
                                        vStringLength = i - vStringStart;
                                        goto Run2;
                                    }
                                }
                                throw new Exception(Debug(str, i, "字符串未结束 " + *now));
                            Run2:
                                // 下必 ,} 
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    switch (*now)
                                    {
                                        case ',':
                                            //string入队
                                            //json_value = &pool[poolIndex++];
                                            pool[poolIndex].type = JsonValueType.String;
                                            pool[poolIndex].keyStringLength = keyStringLength;
                                            pool[poolIndex].keyStringStart = keyStringStart;
                                            pool[poolIndex].vStringStart = vStringStart;
                                            pool[poolIndex].vStringLength = vStringLength;
                                            pool[poolIndex].objectQueueIndex = stack[stackIndex];
                                            ++poolIndex;

                                            goto State_Object;
                                        case '}':
                                            //string入队
                                            //json_value = &pool[poolIndex++];
                                            pool[poolIndex].type = JsonValueType.String;
                                            pool[poolIndex].keyStringLength = keyStringLength;
                                            pool[poolIndex].keyStringStart = keyStringStart;
                                            pool[poolIndex].vStringStart = vStringStart;
                                            pool[poolIndex].vStringLength = vStringLength;
                                            pool[poolIndex].objectQueueIndex = stack[stackIndex];
                                            ++poolIndex;

                                            //objectNext 赋值
                                            //(*jsonStackNow)->objectIndex = poolIndex;
                                            //出栈 
                                            --stackIndex;

                                            if (stackIndex == -1)
                                            {
                                                goto BACK;
                                            }
                                            if (objectQueue[stack[stackIndex]].isObject)
                                            {
                                                goto State_Object;
                                            }
                                            else
                                            {
                                                objectQueue[stack[stackIndex + 1]].arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                                ++objectQueue[stack[stackIndex]].arrayCount;
                                                goto State_Array;
                                            }
                                        //goto Loop;
                                        case ' ':
                                        case '\t':
                                        case '\r':
                                        case '\n':
                                            break;
                                        default:
                                        throw new Exception(Debug(str, i, "key:value后面只能是,或者} " + *now));
                                    }
                                }
                                throw new Exception(Debug(str, i, "key:value后面必须要跟,或者} 未正常 结尾 " + *now));

                            case '{':
                                //新建object赋予string名字 object入栈
                                objectQueue[objectQueueIndex].parentObjectIndex = stack[stackIndex];
                                objectQueue[objectQueueIndex].keyStringStart = keyStringStart;
                                objectQueue[objectQueueIndex].keyStringLength = keyStringLength;
                                objectQueue[objectQueueIndex].isObject = true;

                                stack[++stackIndex] = objectQueueIndex;
                                ++objectQueueIndex;

                                goto State_Object;

                            case '[':

                                //新建array赋予string名字 array入栈
                                objectQueue[objectQueueIndex].parentObjectIndex = stack[stackIndex];
                                objectQueue[objectQueueIndex].keyStringStart = keyStringStart;
                                objectQueue[objectQueueIndex].keyStringLength = keyStringLength;
                                objectQueue[objectQueueIndex].isObject = false;
                                objectQueue[objectQueueIndex].arrayCount = 0;

                                stack[++stackIndex] = objectQueueIndex;
                                ++objectQueueIndex;

                                goto State_Array;


                            case 't':
                                if (i < length + 4)
                                {
                                    long nameLong = *(long*)(now);
                                    if (nameLong == truelong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.Boolean;
                                        json_value.valueBool = true;
                                        now += 4;
                                        i += 4;
                                        goto Value;
                                    }
                                }
                                throw new Exception(Debug(str, i, "key:后面的value解析错误 " + *now));
                            case 'n':
                                if (i < length + 4)
                                {
                                    long nameLong = *(long*)(now);
                                    if (nameLong == nulllong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.None;
                                        now += 4;
                                        i += 4;
                                        goto Value;
                                    }
                                }
                                throw new Exception(Debug(str, i, "key:后面的value解析错误 " + *now));
                            case 'f':
                                if (i < length + 4)
                                {
                                    ++now;
                                    ++i;
                                    long nameLong = *(long*)(now);
                                    if (nameLong == alselong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.Boolean;
                                        json_value.valueBool = false;
                                        now += 4;
                                        i += 4;
                                        goto Value;
                                    }
                                }
                                throw new Exception(Debug(str, i, "key:后面的value解析错误 " + *now));
                            default:
                                fu = false;
                                if (*now < '0' || *now > '9')
                                {
                                    if (*now == '-')
                                    {
                                        fu = true;
                                        //负号后面可以加空格
                                        for (++i, ++now; i < length; ++i, ++now)
                                        {
                                            if (*now != ' ')
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    else if (*now == '+')
                                    {
                                        ++i; ++now;
                                    }
                                    else
                                    {
                                        throw new Exception(Debug(str, i, "key:value后面必须要跟,或者} " + *now));
                                    }
                                }
                                json_value = pool[poolIndex++];
                                v_long = (*now - '0');
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now < '0' || *now > '9')
                                    {
                                        if (*now == '.')
                                        {
                                            goto Dot;
                                        }
                                        else
                                        {
                                            json_value.type = JsonValueType.Long;
                                            json_value.valueLong = fu ? -v_long : v_long;
                                            goto Value;
                                        }
                                    }
                                    else
                                    {
                                        v_long *= 10;
                                        v_long += (*now - '0');
                                    }
                                }
                                //long
                                throw new Exception(Debug(str, i, "key:value后面必须要跟,或者} " + *now));

                            Dot:
                                v_double = v_long;
                                //点
                                v_decimal = 0.1;
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now < '0' || *now > '9')
                                    {
                                        if (*now == 'E' || *now == 'e')
                                        {
                                            ++now; ++i;
                                            if (*now == '-')
                                            {
                                                v_long = 0;

                                                for (++i, ++now; i < length; ++i, ++now)
                                                {
                                                    if (*now < '0' || *now > '9')
                                                    {
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        v_long *= 10;
                                                        v_long += (*now - '0');
                                                    }
                                                }
                                                v_double *= pow309negative[v_long];
                                                json_value.type = JsonValueType.Double;
                                                json_value.valueDouble = fu ? -v_double : v_double;
                                                goto Value;
                                            }
                                            else if (*now == '+')
                                            {
                                                v_long = 0;

                                                for (++i, ++now; i < length; ++i, ++now)
                                                {
                                                    if (*now < '0' || *now > '9')
                                                    {
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        v_long *= 10;
                                                        v_long += (*now - '0');
                                                    }
                                                }
                                                v_double *= pow309[v_long];
                                                json_value.type = JsonValueType.Double;
                                                json_value.valueDouble = fu ? -v_double : v_double;
                                                goto Value;
                                            }

                                        }
                                        break;
                                    }
                                    else
                                    {
                                        v_double += (*now - '0') * v_decimal;
                                        v_decimal *= 0.1;
                                    }
                                }
                                json_value.type = JsonValueType.Double;
                                json_value.valueDouble = fu ? -v_double : v_double;
                            //goto Value;
                            //throw new Exception("key:后面的value解析错误");

                            Value:

                                for (; i < length; ++i, ++now)
                                {
                                    switch (*now)
                                    {
                                        case ' ':
                                        case '\t':
                                        case '\r':
                                        case '\n':
                                            break;

                                        case ',':
                                            json_value.keyStringLength = keyStringLength;
                                            json_value.keyStringStart = keyStringStart;
                                            json_value.objectQueueIndex = stack[stackIndex];
                                            pool[poolIndex - 1] = json_value;

                                            goto State_Object;
                                        case '}':

                                            json_value.keyStringLength = keyStringLength;
                                            json_value.keyStringStart = keyStringStart;
                                            json_value.objectQueueIndex = stack[stackIndex];
                                            pool[poolIndex - 1] = json_value;

                                            //objectNext 赋值
                                            //(*jsonStackNow)->objectIndex = poolIndex;
                                            //出栈 
                                            --stackIndex;

                                            if (stackIndex == -1)
                                            {
                                                goto BACK;
                                            }
                                            if (objectQueue[stack[stackIndex]].isObject)
                                            {
                                                goto State_Object;
                                            }
                                            else
                                            {
                                                objectQueue[stack[stackIndex + 1]].arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                                ++objectQueue[stack[stackIndex]].arrayCount;
                                                goto State_Array;
                                            }
                                        //goto Loop;
                                        default:
                                            throw new Exception("key:value后面必须要跟,或者} ,");
                                    }
                                }
                                throw new Exception("key:value后面必须要跟,或者} ,未正常结尾");

                            case ' ':
                            case '\t':
                            case '\r':
                            case '\n':
                                break;

                            case ':':
                            case '}':
                            case ',':
                            case ']':
                                throw new Exception("key:后面不能是" + *now);
                        }
                    }
                //}
                ////else
                //{

                State_Array:
                    //" ]
                    for (++i, ++now; i < length; ++i, ++now)
                    {
                        switch (*now)
                        {
                            case '"':
                                json_value = pool[poolIndex++];
                                vStringStart = i + 1;
                                //再找" 
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now == '"')
                                    {
                                        vStringLength = i - vStringStart;
                                        for (++i, ++now; i < length; ++i, ++now)
                                        {
                                            //必出 , ]
                                            if (*now == ',')
                                            {
                                                json_value.type = JsonValueType.String;
                                                json_value.vStringStart = vStringStart;
                                                json_value.vStringLength = vStringLength;
                                                json_value.objectQueueIndex = stack[stackIndex];
                                                json_value.arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                                pool[poolIndex - 1] = json_value;
                                                ++objectQueue[stack[stackIndex]].arrayCount;
                                                goto State_Array;
                                            }
                                            else if (*now == ']')
                                            {
                                                json_value.type = JsonValueType.String;
                                                json_value.vStringStart = vStringStart;
                                                json_value.vStringLength = vStringLength;
                                                json_value.objectQueueIndex = stack[stackIndex];
                                                json_value.arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                                pool[poolIndex - 1] = json_value;
                                                ++objectQueue[stack[stackIndex]].arrayCount;
                                                //出栈
                                                --stackIndex;
                                                goto Loop;
                                            }
                                        }
                                        throw new Exception("key后面需要:");
                                    }
                                }
                                throw new Exception("字符串未结束 ");

                            case '{':
                                //数组元素没有Key
                                // { 新建 object 入栈
                                objectQueue[objectQueueIndex].parentObjectIndex = stack[stackIndex];
                                objectQueue[objectQueueIndex].isObject = true;

                                stack[++stackIndex] = objectQueueIndex;
                                ++objectQueueIndex;

                                goto State_Object;
                            //goto Loop;

                            case '[':
                                // [新建 array 入栈
                                objectQueue[objectQueueIndex].parentObjectIndex = stack[stackIndex];
                                objectQueue[objectQueueIndex].isObject = false;
                                objectQueue[objectQueueIndex].arrayCount = 0;
                                objectQueue[objectQueueIndex].arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                json_value.arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                ++objectQueue[stack[stackIndex]].arrayCount;

                                stack[++stackIndex] = objectQueueIndex;
                                ++objectQueueIndex;

                                goto State_Array;
                            case 't':
                                if (i < length + 4)
                                {
                                    long nameLong = *(long*)(now);
                                    if (nameLong == truelong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.Boolean;
                                        json_value.valueBool = true;
                                        now += 4;
                                        i += 4;
                                        goto Value2;
                                    }
                                }
                                throw new Exception("key:后面的value解析错误");
                            case 'n':
                                if (i < length + 4)
                                {
                                    long nameLong = *(long*)(now);
                                    if (nameLong == nulllong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.None;
                                        now += 4;
                                        i += 4;
                                        goto Value2;
                                    }
                                }
                                throw new Exception("key:后面的value解析错误");
                            case 'f':
                                if (i < length + 4)
                                {
                                    ++now;
                                    ++i;
                                    long nameLong = *(long*)(now);
                                    if (nameLong == alselong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.Boolean;
                                        json_value.valueBool = false;
                                        now += 4;
                                        i += 4;
                                        goto Value2;
                                    }
                                }
                                throw new Exception("key:后面的value解析错误");
                            default:
                                fu = false;
                                if (*now < '0' || *now > '9')
                                {
                                    if (*now == '-')
                                    {
                                        fu = true;
                                        //负号后面可以加空格
                                        for (++i, ++now; i < length; ++i, ++now)
                                        {
                                            if (*now != ' ')
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    else if (*now == '+')
                                    {
                                        ++i; ++now;
                                    }
                                    else
                                    {
                                        throw new Exception("key:value后面必须要跟,或者}" + *now);
                                    }
                                }
                                json_value = pool[poolIndex++];
                                v_long = (*now - '0');
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now < '0' || *now > '9')
                                    {
                                        if (*now == '.')
                                        {
                                            goto Dot2;
                                        }
                                        else
                                        {
                                            json_value.type = JsonValueType.Long;
                                            json_value.valueLong = fu ? -v_long : v_long;
                                            goto Value2;
                                        }
                                    }
                                    else
                                    {
                                        v_long *= 10;
                                        v_long += (*now - '0');
                                    }
                                }
                                //long
                                throw new Exception("key:value后面必须要跟,或者}" + *now);

                            Dot2:
                                v_double = v_long;
                                //点
                                v_decimal = 0.1;
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now < '0' || *now > '9')
                                    {
                                        if (*now == 'E' || *now == 'e')
                                        {
                                            ++now; ++i;
                                            if (*now == '-')
                                            {
                                                v_long = 0;

                                                for (++i, ++now; i < length; ++i, ++now)
                                                {
                                                    if (*now < '0' || *now > '9')
                                                    {
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        v_long *= 10;
                                                        v_long += (*now - '0');
                                                    }
                                                }
                                                v_double *= pow309negative[v_long];
                                                json_value.type = JsonValueType.Double;
                                                json_value.valueDouble = fu ? -v_double : v_double;
                                                goto Value2;
                                            }
                                            else if (*now == '+')
                                            {
                                                v_long = 0;

                                                for (++i, ++now; i < length; ++i, ++now)
                                                {
                                                    if (*now < '0' || *now > '9')
                                                    {
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        v_long *= 10;
                                                        v_long += (*now - '0');
                                                    }
                                                }
                                                v_double *= pow309[v_long];
                                                json_value.type = JsonValueType.Double;
                                                json_value.valueDouble = fu ? -v_double : v_double;
                                                goto Value2;
                                            }

                                        }
                                        break;
                                    }
                                    else
                                    {
                                        v_double += (*now - '0') * v_decimal;
                                        v_decimal *= 0.1;
                                    }
                                }
                                json_value.type = JsonValueType.Double;
                                json_value.valueDouble = fu ? -v_double : v_double;
                            //goto Value;
                            //throw new Exception("key:后面的value解析错误");

                            Value2:
                                json_value.objectQueueIndex = stack[stackIndex];
                                //pool[poolIndex - 1] = json_value;
                                for (; i < length; ++i, ++now)
                                {
                                    switch (*now)
                                    {
                                        case ' ':
                                        case '\t':
                                        case '\r':
                                        case '\n':
                                            break;

                                        case ',':
                                            json_value.arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                            ++objectQueue[stack[stackIndex]].arrayCount;
                                            pool[poolIndex - 1] = json_value;
                                            goto State_Array;
                                        case ']':
                                            //出栈 
                                            json_value.arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                            ++objectQueue[stack[stackIndex]].arrayCount;

                                            pool[poolIndex - 1] = json_value;
                                            --stackIndex;
                                            goto Loop;
                                        default:
                                            throw new Exception(Debug(str, i, "array后面必须要跟,或者] , " + *now));
                                    }
                                }
                                throw new Exception("array后面必须要跟,或者] ,未正常结尾");

                            case ' ':
                            case '\t':
                            case '\r':
                            case '\n':
                            case ',':
                                break;
                            case ']':
                                //(*jsonStackNow)->objectIndex = poolIndex;
                                //出栈 
                                --stackIndex;
                                goto Loop;

                            case ':':
                            case '}':
                                throw new Exception("key:后面不能是" + *now);
                        }
                    }

                    //}

                    //DBJ
                }
                while (stackIndex >= 0);
            }
        BACK:

            //JsonValue[] over = new JsonValue[poolIndex];
            //fixed (JsonValue* vs = &over[0])
            //{
            //    Marshal.ReAllocHGlobal(poolIntPtr, new IntPtr( * sizeof(JsonValue)));
            //    new IntPtr((void*)vs);
            //}
            return poolIndex;

            //return Marshal.GetObjectsForNativeVariants<JsonValue>(poolIntPtr, poolIndex * sizeof(JsonValue));
        }
        public unsafe T ReadJsonTextCreateObject<T>(string str)
        {
            ReadJsonText(str);
            return  (T)CreateObject( typeof(T),  str);
        }

        class RankArray
        {

        }
        BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
        public unsafe object CreateObject(Type type, string str)
        {
            int length = str.Length;
            CreateObjectItem[] createObjectItems = new CreateObjectItem[objectQueueIndex];
            fixed (char* vs = str)
            {
                createObjectItems[0] = new CreateObjectItem(0);
                createObjectItems[0].type = type;
                createObjectItems[0].obj = System.Activator.CreateInstance(type);
                createObjectItems[0].isValueType = type.IsValueType;
                createObjectItems[0].jsonObject = objectQueue[0];

                //对象数组创建
                for (int i = 1; i < objectQueueIndex; i++)
                {
                    CreateObjectItem myObject = createObjectItems[i] = new CreateObjectItem(i);
                    JsonObject v = objectQueue[i];
                    JsonObject parent = objectQueue[v.parentObjectIndex];
                    CreateObjectItem parentObject = createObjectItems[v.parentObjectIndex];
                    createObjectItems[i].jsonObject = objectQueue[i];

                    parentObject.sub.Add(myObject);
                    if (parent.isObject)
                    {
                        ICollectionObjectBase collectionParent = parentObject.collectionObject;
                        if (collectionParent == null)
                        {
                            string key = new string(vs, v.keyStringStart, v.keyStringLength);
                            var fieldInfo = parentObject.type.GetField(key, bindingFlags);

                            myObject.key = key;
                            myObject.fieldInfo = fieldInfo;
                            if (v.isCommandValue)
                            {
                                string typeName = new string(vs, v.typeStartIndex, v.typeLength);
                                var valueType = Type.GetType(typeName);
                                myObject.type = typeof(Box<>).MakeGenericType(valueType);
                            }
                            else
                            {
                                if (v.typeLength > 0)
                                {
                                    string typeName = new string(vs, v.typeStartIndex, v.typeLength);
                                    myObject.type = Type.GetType(typeName);
                                }
                                else
                                {
                                    myObject.type = fieldInfo.FieldType;
                                }
                            }
                        }
                        else
                        {
                            if (v.typeLength > 0)
                            {
                                myObject.type = Type.GetType(new string(vs, v.typeStartIndex, v.typeLength));
                            }
                            else
                            {
                                myObject.type = collectionParent.GetItemType(vs + v.keyStringStart, v.keyStringLength);
                            }
                        }
                    }
                    else
                    {
                        if (v.typeLength > 0)
                        {
                            if (v.isCommandValue)
                            {
                                string typeName = new string(vs, v.typeStartIndex, v.typeLength);
                                var valueType = Type.GetType(typeName);
                                myObject.type = typeof(Box<>).MakeGenericType(valueType);
                            }
                            else
                            {
                                myObject.type = Type.GetType(new string(vs, v.typeStartIndex, v.typeLength));
                            }
                        }
                        else
                        {
                            ICollectionArrayBase collectionParent = parentObject.collectionArray;
                            if (collectionParent == null)
                            {
                                myObject.type = parentObject.ArrayItemType;
                            }
                            else
                            {
                                myObject.type = collectionParent.GetItemType(v.arrayIndex);
                            }
                        }
                    }

                    myObject.sourceType = myObject.type;
                    //"#create"
                    if (v.isConstructor)
                    {
                        myObject.type = typeof(ConstructorWarp);
                    }

                    if (v.isObject)
                    {
                        ICollectionObjectBase collection;
                        if (CollectionManager.formatterAllObjectMap.TryGetValue(myObject.type, out collection))
                        {
                            myObject.obj = collection.Create(myObject.sourceType, parentObject.type);
                            myObject.collectionObject = collection;
                        }
                        else
                        {
                            Type collectionType;
                            if (myObject.type.IsGenericType && CollectionManager.formatterObjectTypeMap.TryGetValue(myObject.type.GetGenericTypeDefinition(), out collectionType))
                            {
                                Type type1 = collectionType.MakeGenericType(myObject.type.GetGenericArguments());
                                CollectionManager.formatterAllObjectMap[myObject.type] = collection
                                    = Activator.CreateInstance(type1) as ICollectionObjectBase;

                                myObject.obj = collection.Create(myObject.type, parentObject.type);
                                myObject.collectionObject = collection;
                            }
                            else
                            {
                                myObject.obj = Activator.CreateInstance(myObject.type);
                            }
                        }
                    }
                    else
                    {
                        ICollectionArrayBase collection;
                        if (CollectionManager.formatterAllArrayMap.TryGetValue(myObject.type, out collection))
                        {
                            myObject.obj = collection.Create(v.arrayCount, myObject.type, parentObject.type);
                            myObject.collectionArray = collection;
                        }
                        else
                        {
                            if (myObject.type.IsGenericType)
                            {
                                Type collectionType;
                                if (CollectionManager.formatterArrayTypeMap.TryGetValue(myObject.type.GetGenericTypeDefinition(), out collectionType))
                                {
                                    Type type1 = collectionType.MakeGenericType(myObject.type.GetGenericArguments());
                                    CollectionManager.formatterAllArrayMap[myObject.type] = collection
                                        = Activator.CreateInstance(type1) as ICollectionArrayBase;

                                    myObject.obj = collection.Create(v.arrayCount, myObject.type, parentObject.type);
                                    myObject.collectionArray = collection;
                                }
                                else
                                {
                                    if (myObject.type.IsSubclassOf(typeof(MulticastDelegate)))
                                    {
                                        collection = CollectionManager.formatterAllArrayMap[typeof(MulticastDelegate)];
                                        myObject.obj = collection.Create(v.arrayCount, myObject.type, parentObject.type);
                                        myObject.collectionArray = collection;
                                    }
                                    else
                                    {
                                        //myObject.obj = Activator.CreateInstance(myObject.type);
                                        throw new Exception("JSON数组类型容器未注册");
                                    }
                                }
                            }
                            else
                            {
                                if (myObject.type.IsArray)
                                {
                                    var rank = myObject.type.GetArrayRank();
                                    //var lengths = myObject.type.getl();
                                    //Array array = Array.CreateInstance(elementType, lengths);
                                    var elementType = myObject.type.GetElementType();
                                    if (rank == 1)//数组的秩= 1 直接遍历赋值
                                    {
                                        myObject.ArrayRank = 1;
                                        myObject.ArrayItemType = elementType;
                                        myObject.ArrayItemTypeCode = Type.GetTypeCode(elementType);
                                        myObject.obj = myObject.objArray = Array.CreateInstance(elementType, v.arrayCount);
                                    }
                                    else
                                    {
                                        if (parentObject.type.IsArray && parentObject.ArrayRank > 1)
                                        {
                                            myObject.ArrayRank = parentObject.ArrayRank - 1;
                                            myObject.ArrayRankLengths = parentObject.ArrayRankLengths;
                                            myObject.ArrayRankIndex = new int[parentObject.ArrayRankIndex.Length];
                                            parentObject.ArrayRankIndex.CopyTo(myObject.ArrayRankIndex, 0);


                                            myObject.ArrayRankIndex[parentObject.ArrayRankIndex.Length - parentObject.ArrayRank] = v.arrayIndex;

                                            myObject.obj = myObject.objArray = parentObject.objArray;
                                            if (myObject.ArrayRank == 1)
                                            {
                                                myObject.ArrayItemType = elementType;
                                                myObject.ArrayItemTypeCode = Type.GetTypeCode(elementType);
                                            }
                                            else
                                            {
                                                myObject.ArrayItemType = myObject.type;
                                            }
                                        }
                                        else
                                        {
                                            myObject.ArrayRank = rank;
                                            myObject.ArrayItemType = myObject.type;
                                            //myObject.ArrayItemType = elementType;
                                            myObject.ArrayItemTypeCode = Type.GetTypeCode(elementType);
                                            myObject.ArrayRankLengths = new int[rank];

                                            if (rank + i > objectQueueIndex)
                                            {
                                                throw new Exception("无法满足秩");
                                            }

                                            myObject.ArrayRankLengths[0] = v.arrayCount;
                                            for (int j = 1; j < rank; j++)
                                            {
                                                JsonObject v1 = objectQueue[j + i];
                                                if (v1.parentObjectIndex == j + i - 1 && !v1.isObject)
                                                {
                                                    myObject.ArrayRankLengths[j] = v1.arrayCount;
                                                }
                                                else
                                                {
                                                    throw new Exception("无法满足秩");
                                                }
                                            }
                                            myObject.obj = myObject.objArray = Array.CreateInstance(elementType, myObject.ArrayRankLengths);
                                            myObject.ArrayRankIndex = new int[rank];
                                        }

                                    }
                                }
                                else
                                {
                                    throw new Exception("类型不是数组");
                                }
                            }
                        }
                    }
                }

                object set_value = null;
                //基本类型赋值
                for (int i = 0; i < poolIndex; i++)
                {
                    var v = pool[i];
                    CreateObjectItem myObject = createObjectItems[v.objectQueueIndex];
                    JsonObject parent = objectQueue[v.objectQueueIndex];
                    if (parent.isObject)
                    {
                        ICollectionObjectBase collection = myObject.collectionObject;
                        if (collection != null)
                        {
                            collection.AddValue(myObject.obj, vs + v.keyStringStart, v.keyStringLength, vs, &v);
                        }
                        else
                        {
                            string key = new string(vs, v.keyStringStart, v.keyStringLength);
                            FieldInfo fieldInfo = myObject.type.GetField(key, bindingFlags);
                            var itemTypeCode = Type.GetTypeCode(fieldInfo.FieldType);
                            switch (v.type)
                            {
                                case JsonValueType.String:
                                    switch (itemTypeCode)
                                    {
                                        case TypeCode.Char:
                                            fieldInfo.SetValue(
                                                myObject.obj, vs[v.vStringStart]);
                                            break;
                                        case TypeCode.String:
                                            fieldInfo.SetValue(
                                                myObject.obj,
                                                new string(vs, v.vStringStart, v.vStringLength));
                                            break;
                                        case TypeCode.Object:

                                            fieldInfo.SetValue(
                                                myObject.obj, PathToObject(vs + v.vStringStart, v.vStringLength, createObjectItems[0]));

                                            break;
                                        default:

                                            if (fieldInfo.FieldType.IsEnum)
                                            {
                                                var strEnum = new string(vs, v.vStringStart, v.vStringLength);
                                                Array Arrays = Enum.GetValues(fieldInfo.FieldType);
                                                for (int k = 0; k < Arrays.Length; k++)
                                                {
                                                    if (Arrays.GetValue(k).ToString().Equals(strEnum))
                                                    {
                                                        fieldInfo.SetValue(
                                                            myObject.obj, Arrays.GetValue(i));
                                                    }
                                                }
                                            }
                                            break;
                                    }
                                    break;
                                case JsonValueType.Long:
                                    switch (itemTypeCode)
                                    {
                                        case TypeCode.SByte:
                                            fieldInfo.SetValue(
                                                myObject.obj, (SByte)v.valueLong);
                                            break;
                                        case TypeCode.Byte:
                                            fieldInfo.SetValue(
                                                myObject.obj, (Byte)v.valueLong);
                                            break;
                                        case TypeCode.Int16:
                                            fieldInfo.SetValue(
                                                myObject.obj, (Int16)v.valueLong);
                                            break;
                                        case TypeCode.UInt16:
                                            fieldInfo.SetValue(
                                                myObject.obj, (UInt16)v.valueLong);
                                            break;
                                        case TypeCode.Int32:
                                            fieldInfo.SetValue(
                                                myObject.obj, (Int32)v.valueLong);
                                            break;
                                        case TypeCode.UInt32:
                                            fieldInfo.SetValue(
                                                myObject.obj, (UInt32)v.valueLong);
                                            break;
                                        case TypeCode.Int64:
                                            fieldInfo.SetValue(
                                                myObject.obj, v.valueLong);
                                            break;
                                        case TypeCode.UInt64:
                                            fieldInfo.SetValue(
                                                myObject.obj, (UInt64)v.valueLong);
                                            break;
                                        case TypeCode.Single:
                                            fieldInfo.SetValue(
                                                myObject.obj, (Single)v.valueLong);
                                            break;
                                        case TypeCode.Double:
                                            fieldInfo.SetValue(
                                                myObject.obj, (Double)v.valueLong);
                                            break;
                                        case TypeCode.Decimal:
                                            fieldInfo.SetValue(
                                                myObject.obj, (Decimal)v.valueLong);
                                            break;
                                    }
                                    break;
                                case JsonValueType.Double:
                                    switch (itemTypeCode)
                                    {
                                        case TypeCode.Single:
                                            fieldInfo.SetValue(
                                                myObject.obj, (Single)v.valueDouble);
                                            break;
                                        case TypeCode.Double:
                                            fieldInfo.SetValue(
                                                myObject.obj, v.valueDouble);
                                            break;
                                        case TypeCode.Decimal:
                                            fieldInfo.SetValue(
                                                myObject.obj, (Decimal)v.valueDouble);
                                            break;
                                    }
                                    break;
                                case JsonValueType.Boolean:
                                    fieldInfo.SetValue(
                                        myObject.obj, v.valueBool);
                                    break;
                                case JsonValueType.Object:
                                    if (myObject.type == (typeof(Type)))
                                    {
                                        fieldInfo.SetValue(
                                            myObject.obj, Type.GetType(new string(vs, v.vStringStart, v.vStringLength)));
                                    }
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                    else
                    {
                        ICollectionArrayBase collection = myObject.collectionArray;
                        if (collection != null)
                        {
                            collection.AddValue(myObject.obj, v.arrayIndex, vs, &v);
                        }
                        else
                        {
                            Type itemType;
                            TypeCode itemTypeCode;
                            if (v.typeLength > 0)
                            {
                                string typeName = new string(vs, v.typeStartIndex, v.typeLength);
                                itemType = Type.GetType(typeName);
                                itemTypeCode = Type.GetTypeCode(itemType);
                            }
                            else
                            {
                                itemType = myObject.ArrayItemType;
                                itemTypeCode = myObject.ArrayItemTypeCode;
                            }
                            switch (v.type)
                            {
                                case JsonValueType.String:
                                    switch (itemTypeCode)
                                    {
                                        case TypeCode.Char:
                                            set_value = vs[v.vStringStart];
                                            break;
                                        case TypeCode.String:
                                            set_value = new string(vs, v.vStringStart, v.vStringLength);
                                            break;
                                        default:
                                            if (myObject.ArrayItemType.IsEnum)
                                            {
                                                var strEnum = new string(vs, v.vStringStart, v.vStringLength);
                                                Array Arrays = Enum.GetValues(myObject.ArrayItemType);
                                                for (int k = 0; k < Arrays.Length; k++)
                                                {
                                                    if (Arrays.GetValue(k).ToString().Equals(strEnum))
                                                    {
                                                        set_value = Arrays.GetValue(i);
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                set_value = PathToObject(vs + v.vStringStart, v.vStringLength, createObjectItems[0]);
                                            }
                                            break;
                                    }
                                    break;
                                case JsonValueType.Long:
                                    switch (itemTypeCode)
                                    {
                                        case TypeCode.SByte:
                                            set_value = (SByte)v.valueLong;
                                            break;
                                        case TypeCode.Byte:
                                            set_value = (Byte)v.valueLong;
                                            break;
                                        case TypeCode.Int16:
                                            set_value = (Int16)v.valueLong;
                                            break;
                                        case TypeCode.UInt16:
                                            set_value = (UInt16)v.valueLong;
                                            break;
                                        case TypeCode.Int32:
                                            set_value = (Int32)v.valueLong;
                                            break;
                                        case TypeCode.UInt32:
                                            set_value = (UInt32)v.valueLong;
                                            break;
                                        case TypeCode.Int64:
                                            set_value = v.valueLong;
                                            break;
                                        case TypeCode.UInt64:
                                            set_value = (UInt64)v.valueLong;
                                            break;
                                        case TypeCode.Single:
                                            set_value = (Single)v.valueLong;
                                            break;
                                        case TypeCode.Double:
                                            set_value = (Double)v.valueLong;
                                            break;
                                        case TypeCode.Decimal:
                                            set_value = (Decimal)v.valueLong;
                                            break;
                                    }
                                    break;
                                case JsonValueType.Double:
                                    switch (itemTypeCode)
                                    {
                                        case TypeCode.Single:
                                            set_value = (Single)v.valueDouble;
                                            break;
                                        case TypeCode.Double:
                                            set_value = (Double)v.valueDouble;
                                            break;
                                        case TypeCode.Decimal:
                                            set_value = (Decimal)v.valueDouble;
                                            break;
                                    }
                                    break;
                                case JsonValueType.Boolean:
                                    set_value = v.valueBool;
                                    break;
                                case JsonValueType.Object:
                                    if (myObject.type == (typeof(Type)))
                                    {
                                        set_value = Type.GetType(new string(vs, v.vStringStart, v.vStringLength));
                                    }
                                    break;
                            }

                            if (myObject.ArrayRank == 1)
                            {
                                if (myObject.ArrayRankIndex == null)
                                {
                                    myObject.objArray.SetValue(set_value, v.arrayIndex);
                                }
                                else
                                {
                                    myObject.objArray.SetValue(set_value, myObject.ArrayRankIndex);
                                    var nowRank = myObject.ArrayRankIndex.Length - 1;//到下一个秩，相当于进一位
                                Chake:
                                    ++myObject.ArrayRankIndex[nowRank];
                                    if (myObject.ArrayRankIndex[nowRank] == myObject.ArrayRankLengths[nowRank])//进一位
                                    {
                                        --nowRank;
                                        if (nowRank >= 0)
                                        {
                                            goto Chake;
                                        }
                                        else
                                        {
                                            //break;
                                        }
                                    }
                                    //进位后，小位数的下标变成0
                                    for (int k = myObject.ArrayRankIndex.Length - 1; k > nowRank; k--)
                                    {
                                        myObject.ArrayRankIndex[k] = 0;
                                    }
                                }
                            }
                        }
                    }
                }


                //类类型赋值

                for (int i = createObjectItems.Length - 2; i >= 0; i--)
                {
                    CreateObjectItem parentObject = createObjectItems[i];
                    JsonObject parent = objectQueue[parentObject.index];
                    foreach (var myObject in createObjectItems[i].sub)
                    {
                        JsonObject v = objectQueue[myObject.index];
                        if (v.isObject)
                        {
                            ICollectionObjectBase collection = myObject.collectionObject;
                            if (collection != null)
                            {
                                myObject.obj = collection.End(myObject.obj);
                            }
                        }
                        else
                        {
                            ICollectionArrayBase collection = myObject.collectionArray;
                            if (collection != null)
                            {
                                myObject.obj = collection.End(myObject.obj);
                            }
                        }



                        if (parent.isObject)
                        {
                            ICollectionObjectBase parentCollection = parentObject.collectionObject;
                            if (parentCollection == null)
                            {
                                myObject.fieldInfo.SetValue(parentObject.obj, myObject.obj);
                            }
                            else
                            {
                                parentCollection.Add(parentObject.obj, vs + v.keyStringStart, v.keyStringLength, myObject.obj);
                            }
                        }
                        else
                        {
                            ICollectionArrayBase parentCollection = parentObject.collectionArray;

                            if (parentCollection == null)
                            {
                                if (parentObject.ArrayRank == 1)
                                {
                                    if (parentObject.ArrayRankIndex == null)
                                    {
                                        parentObject.objArray.SetValue(myObject.obj, v.arrayIndex);
                                    }
                                    else
                                    {
                                        //myObject.objArray.SetValue(set_value, myObject.ArrayRankIndex);

                                        parentObject.ArrayRankIndex[parentObject.ArrayRankIndex.Length - 1] = v.arrayIndex;
                                        parentObject.objArray.SetValue(myObject.obj, parentObject.ArrayRankIndex);
                                    }
                                }
                            }
                            else
                            {
                                parentCollection.Add(parentObject.obj, v.arrayIndex, myObject.obj);
                            }


                        }
                    }
                }




            }




            //Console.ReadKey();
            return createObjectItems[0].obj;
        }

        private object PathToObject(char* nowChar, int vStringLength, CreateObjectItem nowObject)
        {

            var nowSub = nowObject.sub;
            int startKey = 0;
            int index = 0;
            for (int k = 0; k < vStringLength; k++)
            {
                char* now = nowChar + k;
                if (nowObject.jsonObject.isObject)
                {
                    if (*now == '/')
                    {
                        var pathKey = new string(nowChar, startKey, k - startKey);
                        startKey = k + 1;
                        foreach (var sub in nowSub)
                        {
                            if (sub.key == pathKey)
                            {
                                nowSub = sub.sub;
                                nowObject = sub;
                                goto Continue;
                            }
                        }
                        return null;

                    Continue:
                        continue;
                    }
                }
                else
                {
                    if (*now == '/')
                    {
                        startKey = k + 1;
                        if (nowSub[index].jsonObject.arrayIndex == index)
                        {
                            nowObject = nowSub[index];
                            nowSub = nowObject.sub;
                            index = 0;
                            goto Continue;
                        }
                        foreach (var sub in nowSub)
                        {
                            if (sub.jsonObject.arrayIndex == index)
                            {
                                nowSub = sub.sub;
                                nowObject = sub;
                                index = 0;
                                goto Continue;
                            }
                        }
                        return null;

                    Continue:
                        continue;
                    }
                    else
                    {
                        if (*now < '0' || *now > '9')
                        {
                            return null;
                        }
                        else
                        {
                            index *= 10;
                            index += (*now - '0');
                        }
                    }

                }
            }
            if (startKey < vStringLength)
            {
                if (nowObject.jsonObject.isObject)
                {
                    var pathKey = new string(nowChar, startKey, vStringLength - startKey);
                    foreach (var sub in nowSub)
                    {
                        if (sub.key == pathKey)
                        {
                            return sub.obj;
                        }
                    }
                    return null;
                }
                else
                {
                    if (nowSub[index].jsonObject.arrayIndex == index)
                    {
                        return nowSub[index].obj;
                    }
                    foreach (var sub in nowSub)
                    {
                        if (sub.jsonObject.arrayIndex == index)
                        {
                            return sub.obj;
                        }
                    }
                    return null;
                }
            }
            else
            {
                return nowObject.obj;
            }
        }

    }
}
